#include "../lvgl/lvgl.h"

#include "lodepng.h"
#include <time.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>

#include "../my_inc/canvas.h"
#include "../my_inc/shapes.h"
// #include "../my_inc/bmp.h"
#include <math.h>

static lv_color_t canvas_buf[CANVAS_WIDTH * CANVAS_HEIGHT];
static lv_color_t mid_canvas_buf[MID_CANVAS_WIDTH * MID_CANVAS_HEIGHT];
static lv_color_t small_canvas_buf[SMALL_CANVAS_WIDTH * SMALL_CANVAS_HEIGHT];

static lv_point_t prev_point = {-1, -1};

// 事件描述符
// lv_event_dsc_t event_dsc;

// // 数据转换：RGB888 → lv_color_t
// static lv_color_t rgb888_to_color(uint8_t b, uint8_t g, uint8_t r)
// {
// #if LV_COLOR_DEPTH == 16
//     return lv_color_make(r, g, b); // RGB565
// #elif LV_COLOR_DEPTH == 32
//     return lv_color_make(r, g, b); // RGB888
// #else
// #error Unsupported LV_COLOR_DEPTH
// #endif
// }

// static void clear_btn_event_cb(lv_event_t * e);

/* 把 PNG 缩放到当前画布大小，转换png数据并直接写进画布缓冲区 */
bool load_png_to_canvas(const char *png_path)
{
    unsigned char *rgba = NULL;
    unsigned w_raw, h_raw;

    /* 1. 解码 PNG → RGBA */
    unsigned err = lodepng_decode32_file(&rgba, &w_raw, &h_raw, png_path);
    if (err) {
        printf("PNG decode error %u: %s\n", err, lodepng_error_text(err));
        return false;
    }

    /* 2. 根据当前画布尺寸取得目标宽高 */
    uint32_t cw, ch;
    switch (canvas_size) {
        case 1: cw = SMALL_CANVAS_WIDTH;  ch = SMALL_CANVAS_HEIGHT;  break;
        case 2: cw = MID_CANVAS_WIDTH;    ch = MID_CANVAS_HEIGHT;    break;
        default: cw = CANVAS_WIDTH;       ch = CANVAS_HEIGHT;        break;
    }
    lv_color_t *dst_buf = NULL;
    if (canvas_size == 1)      dst_buf = small_canvas_buf;
    else if (canvas_size == 2) dst_buf = mid_canvas_buf;
    else                       dst_buf = canvas_buf;

    /* 3. 最近邻缩放 RGBA → LVGL RGB565（或 RGB888） */
    for (uint32_t y = 0; y < ch; y++) {
        for (uint32_t x = 0; x < cw; x++) {
            /* 映射坐标 */
            uint32_t sx = x * w_raw / cw;
            uint32_t sy = y * h_raw / ch;
            uint8_t *p = rgba + (sy * w_raw + sx) * 4;

            lv_color_t color = lv_color_make(p[0], p[1], p[2]);
            dst_buf[y * cw + x] = color;
        }
    }

    /* 4. 画到画布 */
    lv_canvas_fill_bg(canvas, bg_color, LV_OPA_COVER);
    lv_img_dsc_t img_dsc = {
        .data = dst_buf,
        .header.w = cw,
        .header.h = ch,
        .header.cf = LV_IMG_CF_TRUE_COLOR,
    };
    lv_canvas_draw_img(canvas, 0, 0, &img_dsc, NULL);

    /* 5. 释放内存 */
    free(rgba);
    return true;
}

/* 把 bmp 缩放到当前画布大小，转换bmp数据并直接写进画布缓冲区 */
// bool load_bmp_to_canvas(const char *bmp_path)
// {
//     if (!canvas) return false;

//     /* 1. 目标画布尺寸 */
//     uint32_t cw, ch;
//     lv_color_t *dst = NULL;
//     if (canvas_size == 1)      { cw = SMALL_CANVAS_WIDTH;  ch = SMALL_CANVAS_HEIGHT;  dst = small_canvas_buf; }
//     else if (canvas_size == 2) { cw = MID_CANVAS_WIDTH;    ch = MID_CANVAS_HEIGHT;    dst = mid_canvas_buf; }
//     else                       { cw = CANVAS_WIDTH;        ch = CANVAS_HEIGHT;        dst = canvas_buf; }

//     /* 2. 打开 BMP */
//     FILE *fp = fopen(bmp_path, "rb");
//     if (!fp) { perror("BMP fopen"); return false; }

//     struct tagBITMAPFILEHEADER bmfh;
//     struct tagBITMAPINFOHEADER bmih;
//     fread(&bmfh, sizeof(bmfh), 1, fp);
//     fread(&bmih, sizeof(bmih), 1, fp);

//     if (bmfh.bfType != 0x4D42 || bmih.biBitCount != 24 || bmih.biCompression != 0) {
//         fclose(fp); printf("仅支持 24 位无压缩 BMP\n"); return false;
//     }

//     uint32_t bmp_w = bmih.biWidth;
//     uint32_t bmp_h = abs(bmih.biHeight);
//     uint32_t row_bytes = ((bmp_w * 3 + 3) & ~3); // 4 字节对齐
//     uint8_t *row = malloc(row_bytes);
//     if (!row) { fclose(fp); return false; }

//     fseek(fp, bmfh.bfOffBits, SEEK_SET);

//     /* 3. 最近邻缩放 + 写入画布缓冲区 */
//     for (uint32_t y = 0; y < ch; ++y) {
//         for (uint32_t x = 0; x < cw; ++x) {
//             /* 映射到 BMP 坐标 */
//             uint32_t sx = x * bmp_w / cw;
//             uint32_t sy = y * bmp_h / ch;

//             /* 从底到顶读取 */
//             fseek(fp, bmfh.bfOffBits + (bmp_h - 1 - sy) * row_bytes + sx * 3, SEEK_SET);
//             fread(row, 3, 1, fp);

//             dst[y * cw + x] = rgb888_to_color(row[0], row[1], row[2]);
//         }
//     }

//     free(row);
//     fclose(fp);

//     /* 4. 立即刷新画布 */
//     lv_img_dsc_t img_dsc = {
//         .data = dst,
//         .header.w = cw,
//         .header.h = ch,
//         .header.cf = LV_IMG_CF_TRUE_COLOR,
//     };
//     // lv_img_cache_invalidate();          // 防止旧缓存
//     lv_canvas_fill_bg(canvas, bg_color, LV_OPA_COVER);
//     lv_canvas_draw_img(canvas, 0, 0, &img_dsc, NULL);

//     printf("BMP loaded (%ux%u)\n", cw, ch);
//     return true;
// }

// 创建画布
void create_canvas(lv_obj_t * Panel)
{

    /* 创建画布对象 */
    canvas = lv_canvas_create(Panel);
    if(canvas_size == 1)
    {
        lv_canvas_set_buffer(canvas, small_canvas_buf, SMALL_CANVAS_WIDTH, SMALL_CANVAS_HEIGHT, LV_IMG_CF_TRUE_COLOR);
    }
    else if(canvas_size == 2)
    {
        lv_canvas_set_buffer(canvas, mid_canvas_buf, MID_CANVAS_WIDTH, MID_CANVAS_HEIGHT, LV_IMG_CF_TRUE_COLOR);
    }
    else if(canvas_size == 3)
    {
        lv_canvas_set_buffer(canvas, canvas_buf, CANVAS_WIDTH, CANVAS_HEIGHT, LV_IMG_CF_TRUE_COLOR);
    }
    lv_canvas_fill_bg(canvas, bg_color, LV_OPA_COVER);
    
    /* 画布在Panel内居中对齐 */
    lv_obj_align(canvas, LV_ALIGN_CENTER, 0, 0);
 
    /* 绑定画布事件 */
    lv_obj_add_flag(canvas, LV_OBJ_FLAG_CLICKABLE);

    /* 先移除事件 */
    lv_obj_remove_event_cb(canvas, NULL);
    if(event_flag == EVENT_DRAW)
    {
        lv_obj_add_event_cb(canvas, draw_event_cb, LV_EVENT_PRESSING, NULL);
        lv_obj_add_event_cb(canvas, draw_event_cb_1, LV_EVENT_RELEASED, NULL);
    }
    else if(event_flag == EVENT_SHAPE)
    {
        lv_obj_add_event_cb(canvas, canvas_press_cb,   LV_EVENT_PRESSED,  NULL);
        lv_obj_add_event_cb(canvas, canvas_release_cb, LV_EVENT_RELEASED, NULL);
    }
}

/* 绘图事件处理 */
void draw_event_cb(lv_event_t * e)
{
    lv_obj_t * canvas2 = lv_event_get_target(e);

    lv_point_t point;
    
    /* 获取触摸点坐标 */
    lv_indev_get_point(lv_indev_get_act(), &point);
    
    /* 转换为画布局部坐标 */
    lv_area_t canvas_area;
    lv_obj_get_coords(canvas2, &canvas_area);
    point.x -= canvas_area.x1;
    point.y -= canvas_area.y1;
 
    /* 绘制逻辑 */
    if(prev_point.x != -1) {
        lv_draw_line_dsc_t line_dsc;
        lv_draw_line_dsc_init(&line_dsc);

        // 抗锯齿
        line_dsc.blend_mode = LV_BLEND_MODE_NORMAL;
        line_dsc.dash_width = 0;  // 关闭虚线
        line_dsc.round_start = 1; // 圆角起点
        line_dsc.round_end = 1;   // 圆角终点

        // 画笔颜色和大小
        if (eraser_flag == ERASER_OFF) {
            line_dsc.color = lv_color_hex(0x0000ff);
            line_dsc.width = pen_size;
        }
        else if (eraser_flag == ERASER_ON){
            line_dsc.color = bg_color;
            line_dsc.width = eraser_size;
        }

        line_dsc.opa = LV_OPA_COVER;
            
        lv_point_t points[] = {prev_point, point};
        lv_canvas_draw_line(canvas2, points, 2, &line_dsc);
    }
    prev_point = point;
}

// 松开鼠标事件
void draw_event_cb_1(lv_event_t * e)
{
    prev_point.x = -1;
    prev_point.y = -1;
}

// 清除画布
void clear_canvas(void)
{
    if(canvas != NULL) 
    {
        lv_canvas_fill_bg(canvas, bg_color, LV_OPA_COVER);
    }
    // memset(canvas_buf, 0, sizeof(canvas_buf));  // 清除缓冲区
}


// 截图功能函数
// 保存为png
bool save_canvas_as_png(const char *username)
{
    if(canvas == NULL) 
    {
        printf("画布为空，无法保存!\n");
        return false; // 如果画布为空，则不保存
    }
    /* 1. 根据当前画布尺寸获取缓冲区指针 */
    lv_color_t *buf = NULL;
    uint32_t w = 0, h = 0;

    if (canvas_size == 1) {
        buf = small_canvas_buf;
        w = SMALL_CANVAS_WIDTH;
        h = SMALL_CANVAS_HEIGHT;
    } else if (canvas_size == 2) {
        buf = mid_canvas_buf;
        w = MID_CANVAS_WIDTH;
        h = MID_CANVAS_HEIGHT;
    } else {
        buf = canvas_buf;
        w = CANVAS_WIDTH;
        h = CANVAS_HEIGHT;
    }

    /* 2. 构造目录: /UserFile/<username>/Screenshot/ */
    char dir_path[256];
    snprintf(dir_path, sizeof(dir_path), "/UserFile/%s/Screenshot", username);

    if (access(dir_path, F_OK) != 0) {
        /* 目录不存在，递归创建 */
        char tmp[256];
        snprintf(tmp, sizeof(tmp), "/UserFile/%s", username);
        mkdir("/UserFile", 0755);
        mkdir(tmp, 0755);
        mkdir(dir_path, 0755);
    }

    /* 3. 构造文件名：时间戳.png */
    char file_path[512];
    time_t now = time(NULL);
    struct tm *t = localtime(&now);
    snprintf(file_path, sizeof(file_path),
             "%s/%04d%02d%02d_%02d%02d%02d.png",
             dir_path,
             t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
             t->tm_hour, t->tm_min, t->tm_sec);

    /* 4. 把 LVGL 的 RGB565 / RGB888 转成 RGBA8888 供 lodepng 使用 */
    uint8_t *rgba = malloc(w * h * 4);
    if (!rgba) return false;

    for (uint32_t i = 0; i < w * h; ++i) {
        lv_color_t c = buf[i];
        rgba[i * 4 + 0] = LV_COLOR_GET_R8(c);
        rgba[i * 4 + 1] = LV_COLOR_GET_G8(c);
        rgba[i * 4 + 2] = LV_COLOR_GET_B8(c);
        rgba[i * 4 + 3] = 0xFF;  // 不透明
    }

    /* 5. 编码 PNG */
    unsigned error = lodepng_encode32_file(file_path, rgba, w, h);
    free(rgba);

    if (error) {
        printf("PNG encode error %u: %s\n", error, lodepng_error_text(error));
        return false;
    }

    printf("Saved: %s\n", file_path);
    return true;
}

// // 保存为bmp
// bool save_canvas_as_bmp(const char *username)
// {
//     if (canvas == NULL) {
//         printf("画布为空，无法保存!\n");
//         return false;
//     }

//     /* 1. 取得画布宽高与缓冲区 */
//     uint32_t w, h;
//     lv_color_t *buf = NULL;
//     if (canvas_size == 1)      { w = SMALL_CANVAS_WIDTH;  h = SMALL_CANVAS_HEIGHT;  buf = small_canvas_buf; }
//     else if (canvas_size == 2) { w = MID_CANVAS_WIDTH;    h = MID_CANVAS_HEIGHT;    buf = mid_canvas_buf; }
//     else                       { w = CANVAS_WIDTH;        h = CANVAS_HEIGHT;        buf = canvas_buf; }

//     /* 2. 构造目录及文件名 */
//     char dir_path[256];
//     snprintf(dir_path, sizeof(dir_path), "/UserFile/%s/Screenshot", username);
//     if (access(dir_path, F_OK) != 0) {
//         char tmp[256];
//         snprintf(tmp, sizeof(tmp), "/UserFile/%s", username);
//         mkdir("/UserFile", 0755);
//         mkdir(tmp, 0755);
//         mkdir(dir_path, 0755);
//     }

//     char file_path[512];
//     time_t now = time(NULL);
//     struct tm *t = localtime(&now);
//     snprintf(file_path, sizeof(file_path),
//              "%s/%04d%02d%02d_%02d%02d%02d.bmp",
//              dir_path,
//              t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
//              t->tm_hour, t->tm_min, t->tm_sec);

//     /* 3. 打开文件 */
//     FILE *fp = fopen(file_path, "wb");
//     if (!fp) { perror("fopen"); return false; }

//     /* 4. 填充 BMP 头（使用你的结构体） */
//     struct tagBITMAPFILEHEADER bmfh = {
//         .bfType = 0x4D42,                 // "BM"
//         .bfSize = 54 + w * h * 3,         // 文件大小
//         .bfReserved1 = 0,
//         .bfReserved2 = 0,
//         .bfOffBits   = 54                 // 像素数据偏移
//     };

//     struct tagBITMAPINFOHEADER bmih = {
//         .biSize        = sizeof(bmih),
//         .biWidth       = w,
//         .biHeight      = h,               // 正数：底到顶
//         .biPlanes      = 1,
//         .biBitCount    = 24,
//         .biCompression = 0,
//         .biSizeImage   = w * h * 3,
//         .biXPelsPerMeter = 0,
//         .biYPelsPerMeter = 0,
//         .biClrUsed     = 0,
//         .biClrImportant = 0
//     };

//     fwrite(&bmfh, sizeof(bmfh), 1, fp);
//     fwrite(&bmih, sizeof(bmih), 1, fp);

//     /* 5. 写像素数据（BGR24，从底到顶） */
//     for (int32_t y = h - 1; y >= 0; --y) {
//         for (uint32_t x = 0; x < w; ++x) {
//             lv_color_t color = buf[y * w + x];
//             uint8_t b = LV_COLOR_GET_B8(color);
//             uint8_t g = LV_COLOR_GET_G8(color);
//             uint8_t r = LV_COLOR_GET_R8(color);
//             fwrite(&b, 1, 1, fp);
//             fwrite(&g, 1, 1, fp);
//             fwrite(&r, 1, 1, fp);
//         }
//     }

//     fclose(fp);
//     printf("Saved BMP: %s\n", file_path);
//     return true;
// }